package Device.Card.UsbCard;

import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbInterface;

import Device.Card.UsbReceiver;
import Interface.IUsbDeviceEvent;

/**
 * Created by GHW on 2017-10-31.
 */

public class UsbHidDevice extends UsbReceiver {

    /**
     * 打开USB设备
     * @param Iusb
     * @return
     *  0 成功
     *  1 无效的设备
     *  2 无权限
     *  3 打开接口失败
     *  4 发送端口无效
     *  5 接收端口无效
     *  6 打开设备链接失败
     *  7 绑定接口失败
     */
    public UsbDeviceConnection OpenUsb(UsbInterface Iusb) {
        usbEndpointOut = Iusb.getEndpoint(1);
        if (usbEndpointOut == null) {
            return null;//发送端口无效
        }
        usbEndpointIn = Iusb.getEndpoint(0);
        if (usbEndpointIn == null) {
            return null;//接收端口无效
        }

        // 在open前判断是否有连接权限；对于连接权限可以静态分配，也可以动态分配权限
        if (usbManager.hasPermission(usbDevice)) {
            usbDeviceConnection = usbManager.openDevice(usbDevice);
        } else {
            return null ;
        }

        if (usbDeviceConnection == null) {
            return null;
        }



        if (usbDeviceConnection.claimInterface(Iusb, true)) {
            return usbDeviceConnection;//绑定接口失败
        }
        return null ;
    }


    /**
     * 关闭设备
     * @param device
     */
    public void CloseUsb(UsbDevice device){
        if (isConnection) {
            isConnection = false;
            if (mctx instanceof IUsbDeviceEvent) {
                ((IUsbDeviceEvent) mctx).UsbLineOffEvent(device, usbDeviceConnection);
            }
            usbDeviceConnection.close();
        }
    }

    //发送数据
    public int sendData(byte[] buffer, int length, int timeout){
        if (!isConnection)
        {
            return -1;
        }
        return usbDeviceConnection.bulkTransfer(usbEndpointOut,buffer,length,timeout);
    }

    //接收数据
    public int receiveData(byte[] buffer, int length, int timeout){
        return usbDeviceConnection.bulkTransfer(usbEndpointIn,buffer,length,timeout);
    }

    //执行命令
    protected int SendCommand(ReaderCommand rc){
        byte [] sendData = new byte[64];
        for(int i = 0; i<64;i++)
        {
            sendData[i] = 0;
        }
        sendData[0] = (byte)0xa2;
        sendData[1] = (byte)0x13;
        sendData[2] = (byte)0xb4;
        sendData[3] = (byte)(rc.getInDataLen()+1);
        sendData[4] = (byte)0x00;
        sendData[5] = (byte)~sendData[3];
        sendData[6] = (byte)~sendData[4];
        sendData[7] = (byte)rc.getCmdCode();
        if (rc.getInDataLen() > 0) {
            for (int i=0; i < rc.getInDataLen(); i++) {
                sendData[i + 8] = rc.getInData()[i];
            }
        }
        byte sTmp = 0;
        for(int i=0;i<sendData[3];i++)
        {
            sTmp += sendData[i+7];
        }
        sendData[8+rc.getInDataLen()] = sTmp;//sum
        int iRet =sendData(sendData,
                64,//9+rc.getInDataLen(),
                1000);
        if (iRet < 0){
            return iRet;
        }

        byte []receiveData = new byte[64];   //根据设备实际情况写数据大小
        try {
            iRet =receiveData(receiveData, receiveData.length, 3000);
            if (iRet < 0){
                return iRet;
            }
            if (iRet < 9){
                return 2;
            }
            //check length
            if ((receiveData[3] > 54)||(receiveData[3]<1)){
                return 3;
            }
            rc.setOutDataLen(receiveData[3]-1);
            //check cmdcode
            if (receiveData[7] != rc.getCmdCode()){
                return 4;
            }
            //check sum
            byte sum = 0;
            for (int i=0;i<receiveData[3];i++)
            {
                sum += receiveData[7+i];
            }
            if (receiveData[8+rc.getOutDataLen()] != sum){
                return 5;
            }
            //set outData
            if (rc.getOutDataLen() > 0)
            {
                for (int i=0;i<rc.getOutDataLen();i++){
                    rc.getOutData()[i] = receiveData[7+i];
                }
            }
            return receiveData[8];
        }catch (Exception e){
            return -2;
        }

    }
}
